/**
 * @file Dogz08ImportDialog.cpp
 *
 * Klasa okna importu danych z DOGZ-a 0.8 - implementacja.
 *
 * @author Zbigniew Siciarz
 * @date 2009
 * @version 2.0.0
 * @since 2.0.0
 */

#include "Dogz08ImportDialog.h"

#include "dogz/Dogz.h"
#include "MessageDialog.h"
#include <QDir>
#include <QFile>
#include <QFileDialog>
#include <QMessageBox>
#include <QProgressDialog>
#include <QString>
#include <QStringList>
#include <QTextStream>


/**
 * Tworzy okno importu, przygotowuje GUI.
 *
 * @param parent obiekt rodzica
 */
Dogz08ImportDialog::Dogz08ImportDialog(QWidget *parent)
    : QDialog(parent), observationsImported(0)
{
	ui.setupUi(this);
}

/**
 * Ustawia tekst pola edycyjnego na wybrany katalog.
 */
void Dogz08ImportDialog::on_btnBrowse_clicked()
{
    QString path = QFileDialog::getExistingDirectory(this,
            tr("Wybierz katalog"));
    if (!path.isEmpty())
    {
        ui.editOldDogzPath->setText(path);
    }
}

/**
 * Wykonuje operację importowania.
 *
 * Weryfikuje, czy podany katalog zawiera plik wykonywalny DOGZ-a. Jeśli tak,
 * wówczas analizuje wszystkie pliki z podkatalogu /oceny/gwiazda/. Można
 * sobie zażyczyć opróżnienia tabeli obserwacji przed importem. Procedura
 * importowania może być czasochłonna, więc wyświetlane jest okno postępu.
 */
void Dogz08ImportDialog::on_btnImport_clicked()
{
    QString path = ui.editOldDogzPath->text();

    // sprawdzamy, czy jest to ścieżka do katalogu programu
    if (!QFile::exists(path + "/dziennik.exe"))
    {
        QMessageBox::information(this, tr("DOGZ"),
                tr("%1 nie jest głównym katalogiem DOGZ-a!").arg(path));
        return;
    }

    // jeśli użytkownik sobie tak zażyczył i potwierdził, to czyścimy tabelę
    if (ui.cbxClearTable->isChecked() &&
            QMessageBox::Yes == QMessageBox::question(this, tr("DOGZ"),
                    tr("Czy na pewno chcesz wyczyścić tabelę obserwacji?"),
                    QMessageBox::Yes | QMessageBox::No))
    {
        Dogz::ObservationManager::clearTables();
    }

    // wczytujemy wszystkie pliki tekstowe z ocenami
    QDir obsDir(path + "/oceny/gwiazda/");
    QStringList files = obsDir.entryList(QStringList() << "*.txt", QDir::Files);
    int filesCount = files.size();

    QProgressDialog progress(tr("Importowanie..."), tr("Anuluj"),
            0, filesCount, this);
    progress.setMinimumDuration(0);

    unsigned int i = 0;
    observationsImported = 0;
    try
    {
        // przetwarzamy pliki z ocenami jeden po drugim
        foreach (QString file, files)
        {
            ++i;
            progress.setValue(i);
            progress.setLabelText(tr("Importowanie pliku %1 (%2 z %3)...").
                    arg(file).arg(i).arg(filesCount));

            importFile(obsDir.absoluteFilePath(file));

            if (progress.wasCanceled())
                break;
            qApp->processEvents();
        }
    }
    catch (Dogz::FileException& e)
    {
        MessageDialog::exception(e);
        return;
    }

    QMessageBox::information(this, tr("DOGZ"),
            tr("Zaimportowano %1 obserwacji.").arg(observationsImported));
}

/**
 * Importuje obserwacje z jednego pliku starego DOGZ-a.
 *
 * @param fileName pełna nazwa pliku (ze ścieżką)
 */
void Dogz08ImportDialog::importFile(const QString& fileName)
{
    QFile file(fileName);
    if (!file.open(QIODevice::ReadOnly))
    {
        throw Dogz::FileException(fileName, tr("Nie można otworzyć pliku %1 do odczytu!").
                arg(fileName));
    }

    // przetwarzanie linia po linii
    QTextStream stream(&file);
    QString line;
    do
    {
        line = stream.readLine();
        importLine(line);
    } while (!line.isNull());
}

/**
 * Importuje pojedynczą obserwację w formacie starego DOGZ-a.
 *
 * Parsuje linię z pliku, wydziela odpowiednie dane, a następnie dodaje do
 * tabeli w bazie danych poprzez managera.
 *
 * @param line jedna obserwacja w formacie DOGZ-a 0.8
 */
void Dogz08ImportDialog::importLine(const QString& line)
{
    QStringList parts = line.split('|');
    if (2 == parts.size())
    {
        // obsługa formatu DOGZ-a 0.8
        QStringList starAndDate = parts[0].split(' ');
        starAndDate.removeLast();
        QString starName = starAndDate.join(" ");
        QStringList jdAndMag = parts[1].split(' ');
        double jd = jdAndMag[0].replace(',', '.').toDouble();
        float mag = jdAndMag[1].replace(',', '.').toFloat();

        Dogz::VisualObservation obs;
        obs.setStarName(Dogz::Star::normalizeStarName(starName));
        obs.setJd(jd);
        obs.setMagnitude(mag);
        Dogz::ObservationManager::addObservation(obs);
        ++observationsImported;
    }
}
